package br.com.oficicar.apresentacao;

import java.util.ArrayList;
import java.util.Collection;

import javax.faces.event.ActionEvent;
import javax.inject.Named;

import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.criterion.Restrictions;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;

import br.com.oficicar.apresentacao.dto.PerfilPermissoesTO;
import br.com.oficicar.entidades.Modulo;
import br.com.oficicar.entidades.Perfil;
import br.com.oficicar.entidades.Permissao;
import br.com.oficicar.integracao.ModuloDAO;
import br.com.oficicar.integracao.PerfilDAO;
import br.com.oficicar.integracao.PermissaoDAO;

@Named
@Controller
@Scope("session")
public class PerfilHome extends GenericHome<Perfil, PerfilDAO> {
	
	private PermissaoDAO permDAO;
	
	private Modulo moduloSelecionado;
	
	private Collection<PerfilPermissoesTO> permissoesModulo;
	
	private TreeNode root;
	
	private TreeNode nodeSelecionado;
	
	private ModuloDAO modDAO;

	private String text;
	private Integer count;
	private boolean bol;
	
	private void montarArvore(Collection<Modulo> modulos, Modulo pai, TreeNode no){
		Collection<Modulo> subList = new ArrayList<Modulo>();
		if(pai==null)
			subList=modulos;
		else
			subList = modDAO.getFilhos(pai);
		
		for (Modulo mod : subList) {
			if(mod.getPai()==null){
				TreeNode childNode = new DefaultTreeNode(mod, no);
				montarArvore(subList, mod, childNode);
			}else if (!no.equals(root)){
				TreeNode childNode = new DefaultTreeNode(mod, no);
				montarArvore(subList, mod, childNode);
			}
		}
	}
	
	//@Transactional(readOnly=true)
	public void onNodeSelect(NodeSelectEvent e){
		if(e.getTreeNode().getData() instanceof Modulo)
		setModuloSelecionado((Modulo) e.getTreeNode().getData());
		carregarPermissoesModulo();
		System.out.println("onNodeSelect: " + getModuloSelecionado());
	}
	
	/**
	 * Este método é utilizado para adicionar ou remover as permissões 
	 * que foram alteradas no Dialog
	 */
	public void aplicarPermissoes(){
		
		for (PerfilPermissoesTO grid : getPermissoesModulo()) {
			if(grid.isAtivo()){
				if(!getEntidade().getPermissao().contains(grid.getPermissao()))
					getEntidade().getPermissao().add(grid.getPermissao());
			}else{
				if(getEntidade().getPermissao().contains(grid.getPermissao()))
					getEntidade().getPermissao().remove(grid.getPermissao());					
			}
		}		
		
		System.out.println("Aplicar permissoes");
	}
	
	@SuppressWarnings("unchecked")
	public void carregarPermissoesModulo(){
		
		setPermissoesModulo(new ArrayList<PerfilPermissoesTO>());
		
		Criteria ct = permDAO.criarCriteria();
		ct.add(Restrictions.eq("modulo", moduloSelecionado));
		Collection<Permissao> permissoesPossiveis = ct.list();
		
		
		for (Permissao permissao : permissoesPossiveis) {
			PerfilPermissoesTO linha = new PerfilPermissoesTO();
			linha.setPermissao(permissao);
			linha.setAtivo(((PerfilDAO)getDaoPrincipal()).isModuloPossuiPermissao(getEntidade(), moduloSelecionado, permissao));
			getPermissoesModulo().add(linha);
		}
		
	}
	
	public TreeNode getRoot() {
		root = new DefaultTreeNode(new Modulo(), null);
//		Collection<Modulo> mods = modDAO.getModulosPerfil(WebUtil.getUsuarioLogado().getPerfil());
		Collection<Modulo> mods = modDAO.listar();
		montarArvore(mods, null, root);
		
		return root;
	}

	public void setRoot(TreeNode root) {
		this.root = root;
	}

	@Autowired
	public void setModDAO(ModuloDAO modDAO) {
		this.modDAO = modDAO;
	}
	
	@Override
	@Transactional(readOnly = true)
	public void selecionar(SelectEvent ev) {
		Perfil entidade = (Perfil) getDaoPrincipal().obter(getEntidade().getId());
		Hibernate.initialize(entidade.getPermissao());
		setEntidade(entidade);
		super.selecionar(ev);
	}
	
	@Override
	public void limparTela() {
		setEntidade(new Perfil());
	}

	@Override
	public void checaRestricoes() {
		
	}
	
	
	
	/*
	 * Gets e Sets
	 */
	
	@Autowired
	public void setPermDAO(PermissaoDAO permDAO) {
		this.permDAO = permDAO;
	}
	
	
	
	public PermissaoDAO getPermDAO() {
		return permDAO;
	}

	public Modulo getModuloSelecionado() {
		return moduloSelecionado;
	}

	public void setModuloSelecionado(Modulo moduloSelecionado) {
		this.moduloSelecionado = moduloSelecionado;
	}

	public TreeNode getNodeSelecionado() {
		return nodeSelecionado;
	}

	public void setNodeSelecionado(TreeNode nodeSelecionado) {
		this.nodeSelecionado = nodeSelecionado;
	}

	public Collection<PerfilPermissoesTO> getPermissoesModulo() {
		return permissoesModulo;
	}

	public void setPermissoesModulo(Collection<PerfilPermissoesTO> permissoesModulo) {
		this.permissoesModulo = permissoesModulo;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public Integer getCount() {
		return count;
	}

	public void setCount(Integer count) {
		this.count = count;
	}

	public boolean isBol() {
		return bol;
	}

	public void setBol(boolean bol) {
		this.bol = bol;
	}

	@Override
	public void iniciarCadastrar(ActionEvent ev) {
		super.iniciarCadastrar(ev);
		setEntidade(new Perfil());
		getEntidade().setPermissao(new ArrayList<Permissao>());
	}

	@Override
	@Autowired
	public void setDaoPrincipal(PerfilDAO daoPrincipal) {
		this.daoPrincipal=daoPrincipal;
	}


}